Migrate MCP Apps support from insiders mode to feature flag with insiders opt-in#2282
Migrate MCP Apps support from insiders mode to feature flag with insiders opt-in#2282mattdholloway wants to merge 4 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR migrates MCP Apps (interactive UI forms) enablement from “insiders mode” to an explicit feature flag (remote_mcp_ui_apps), while keeping backward compatibility by treating insiders mode as implying the flag.
Changes:
- Introduces
github.MCPAppsFeatureFlag(remote_mcp_ui_apps) and wires it through stdio/HTTP feature checking with an insiders-mode transitional fallback. - Adds inventory builder support (
WithMCPApps) to strip/keep MCP Apps UI metadata (Meta["ui"]) based on the feature flag. - Updates tool behavior gates and documentation to reference the feature flag instead of insiders mode.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/inventory/registry_test.go | Renames/extends tests for MCP Apps gating and meta stripping; adds stripMetaKeys coverage. |
| pkg/inventory/builder.go | Adds WithMCPApps, separates insiders stripping from MCP Apps UI metadata stripping, and introduces stripMetaKeys. |
| pkg/http/server.go | Whitelists remote_mcp_ui_apps for X-MCP-Features and adds transitional insiders behavior in feature checker. |
| pkg/http/handler.go | Applies WithInsidersMode and WithMCPApps to the inventory builder based on request context/header features. |
| pkg/github/pullrequests.go | Gates PR UI form behavior on remote_mcp_ui_apps feature flag instead of insiders mode. |
| pkg/github/pullrequests_test.go | Updates UI-gate test setup to use feature checker-based deps rather than InsidersMode. |
| pkg/github/issues.go | Gates issue UI form behavior on remote_mcp_ui_apps feature flag instead of insiders mode. |
| pkg/github/issues_test.go | Updates UI-gate test setup to use feature checker-based deps rather than InsidersMode. |
| pkg/github/feature_flags.go | Adds the exported MCPAppsFeatureFlag constant. |
| internal/ghmcp/server.go | Ensures stdio “insiders mode” also enables remote_mcp_ui_apps; registers UI resources based on the flag. |
| docs/server-configuration.md | Documents feature flags and MCP Apps configuration via X-MCP-Features / --features. |
| docs/insiders-features.md | Removes MCP Apps from insiders-only list; points to feature-flag configuration. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR migrates MCP Apps enablement from being tied to insiders mode to a dedicated feature flag (remote_mcp_ui_apps), while preserving backward compatibility by having insiders mode imply the feature flag.
Changes:
- Introduces
github.MCPAppsFeatureFlagand updates tool handlers (issue_write,create_pull_request) to gate MCP Apps UI behavior via feature flag checks. - Adds transport-specific feature enablement: HTTP via
X-MCP-Features(whitelisted) and stdio via--features, with insiders-mode implication during the transition. - Updates inventory building to strip
uimetadata unless MCP Apps is enabled, and refreshes related tests and docs.
Show a summary per file
| File | Description |
|---|---|
| pkg/github/feature_flags.go | Defines the remote_mcp_ui_apps feature flag constant and documents its purpose. |
| pkg/github/issues.go | Switches UI-gate logic from insiders mode to the MCP Apps feature flag. |
| pkg/github/issues_test.go | Updates UI-gate tests to use feature checker-based enablement instead of insiders mode. |
| pkg/github/pullrequests.go | Switches UI-gate logic from insiders mode to the MCP Apps feature flag. |
| pkg/github/pullrequests_test.go | Updates UI-gate tests to use feature checker-based enablement instead of insiders mode. |
| pkg/http/server.go | Whitelists remote_mcp_ui_apps for X-MCP-Features and adds insiders→flag transitional behavior in the HTTP feature checker. |
| pkg/http/handler.go | Enables MCP Apps inventory behavior based on X-MCP-Features or insiders mode (transitional). |
| pkg/inventory/builder.go | Adds WithMCPApps and strips ui metadata by default unless MCP Apps is enabled; generalizes meta stripping via stripMetaKeys. |
| pkg/inventory/registry_test.go | Renames/adds tests around MCP Apps meta stripping and stripMetaKeys. |
| internal/ghmcp/server.go | Ensures stdio mode treats insiders as implying the feature flag and registers UI resources only when the flag is enabled. |
| docs/server-configuration.md | Documents feature flags and adds MCP Apps configuration examples using X-MCP-Features / --features. |
| docs/insiders-features.md | Removes MCP Apps from insiders-only docs and notes there are currently no insiders-only features. |
Copilot's findings
Comments suppressed due to low confidence (1)
pkg/inventory/registry_test.go:2142
- This test uses
require.Nil(result.Tool.Meta["ui"])(and similar) to assert key stripping, but a map lookup returns nil both when the key is missing and when the key exists with a nil value. To ensurestripMetaKeysactually removes the keys, assert map membership (_, ok := meta["ui"]) rather than only the value.
require.Nil(t, result.Tool.Meta["ui"], "ui should be stripped")
require.Nil(t, result.Tool.Meta["experimental_feature"], "experimental_feature should be stripped")
require.Nil(t, result.Tool.Meta["beta"], "beta should be stripped")
require.Equal(t, "kept", result.Tool.Meta["description"], "description should be preserved")
- Files reviewed: 12/12 changed files
- Comments generated: 2
| Insiders Mode unlocks experimental features. We created this mode to have a way to roll out experimental features and collect feedback. So if you are using Insiders, please don't hesitate to share your feedback with us! Features in Insiders Mode may change, evolve, or be removed based on user feedback. | ||
|
|
||
| > [!NOTE] | ||
| > Insiders mode also enables the `remote_mcp_ui_apps` feature flag for backward compatibility. See [MCP Apps](#mcp-apps) below. |
There was a problem hiding this comment.
Just a flag that this is brittle docs that would need manual update when no longer true.
SamMorrowDrums
left a comment
There was a problem hiding this comment.
Generally happy with this, but it might be nice to avoid the complexity of insiders only and just use feature flags for everything. Insiders would just auto enable a list of feature flags, and all changes would propagate as a consequence.
| if knownSet[flag] && slices.Contains(ghcontext.GetHeaderFeatures(ctx), flag) { | ||
| return true, nil | ||
| } | ||
| // Transitional: insiders mode implies remote_mcp_ui_apps feature flag |
There was a problem hiding this comment.
I'll be honest, I always expected that we would go the other direction here, and all stuff would be a feature flag, and a selection of flags would be available on insiders mode, rather than insiders mode enabling stuff for which there is no feature flag.
Does that make sense? I personally still feel like that. Insiders mode should (where possible), just be a view on a list of feature flags.
| // WithInsidersMode enables or disables insiders mode features. | ||
| // When insiders mode is disabled (default), UI metadata is removed from tools | ||
| // so clients won't attempt to load UI resources. | ||
| // When insiders mode is disabled (default), tools marked InsidersOnly are removed |
There was a problem hiding this comment.
If we do the feature flag list thing, then we don't need the extra complexity here, of transitional stuff. My vote is to remove this, and to just have features that are load bearing for insiders.
| } | ||
|
|
||
| // WithMCPApps enables or disables MCP Apps UI features. | ||
| // When disabled (default), the "ui" Meta key is stripped from tools |
There was a problem hiding this comment.
This can also be done via feature flag.
Summary
This pull request transitions MCP Apps from an insiders-only experimental feature to a general feature flag (
remote_mcp_ui_apps) that can be enabled independently.Why
Closes https://github.com/github/copilot-mcp-core/issues/1471
What changed
MCP Apps feature flag transition and enablement:
remote_mcp_ui_appsfeature flag, not by insiders mode. Insiders mode still enables the flag for backward compatibility. (docs/insiders-features.md,docs/server-configuration.md, [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]WithMCPAppsmethod to control UI metadata, and MCP Apps UI metadata is only included if the feature flag is enabled. (pkg/inventory/builder.go, [1] [2] [3] [4]HTTP and server-side feature flag handling:
X-MCP-Features), with a whitelist for allowed flags (currently onlyremote_mcp_ui_apps). Insiders mode implies the MCP Apps feature flag for compatibility. (pkg/http/server.go, [1] [2] [3]pkg/http/handler.go, [1] [2]Tool handler and test updates:
issue_writeandcreate_pull_requestnow check the MCP Apps feature flag instead of insiders mode to determine UI behavior. (pkg/github/issues.go, [1]pkg/github/pullrequests.go, [2]pkg/github/issues_test.go, [1] [2] [3];pkg/github/pullrequests_test.go, [4] [5]MCP impact
Prompts tested (tool changes only)
Security / limits
Tool renaming
deprecated_tool_aliases.goNote: if you're renaming tools, you must add the tool aliases. For more information on how to do so, please refer to the official docs.
Lint & tests
./script/lint./script/testDocs